/*****************************************************************************
 *  ENTROPY - emerging network to reduce orwellian potency yield
 *
 *  Copyright (C) 2002 Juergen Buchmueller <pullmoll@stop1984.com>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software Foundation,
 *  Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 *
 *	$Id: mime.c,v 1.2 2005/07/12 23:12:29 pullmoll Exp $
 *****************************************************************************/
#include "mime.h"
#include "tools.h"
#include "logger.h"

#ifndef	MAXLINESIZE
#define	MAXLINESIZE	4096
#endif

#define	MIMETYPES	"node/mime.types"

typedef struct mime_s {
	struct mime_s *next;
	char *type;
	int numext;
	char **ext;
}	mime_t;

static mime_t *mime = NULL;
#define	MIME_DEFAULT	"application/octet-stream"

char *auto_mime_type(const char *filename)
{
	mime_t *m;
	const char *ext;
	int n;
	FUN("auto_mime_type");

	ext = strrchr(filename, '.');
	if (NULL == ext) {
		LOG(L_MINOR,("no extension, return default '%s'", MIME_DEFAULT));
		return xstrdup(MIME_DEFAULT);
	}
	ext++;
	for (m = mime; m; m = m->next) {
		for (n = 0; n < m->numext; n++) {
			LOG(L_DEBUGX,("compare '%s' with '%s'\n", ext, m->ext[n]));
			if (0 == strcasecmp(ext, m->ext[n])) {
				LOG(L_MINOR,("'%s' is extension for '%s'",
					ext, m->type));
				return xstrdup(m->type);
			}
		}
	}
	return xstrdup(MIME_DEFAULT);
}

int mime_types(const char *configpath)
{
	char *filename = xcalloc(MAXPATHLEN, sizeof(char));
	FILE *fp = NULL;
	char *line = NULL;
	int e, rc = 0;
	FUN("mime_types");

	pm_snprintf(filename, MAXPATHLEN, "%s%s",
		configpath, MIMETYPES);

	line = xmalloc(MAXLINESIZE);

	fp = fopen(filename, "r");
	if (NULL == fp) {
		LOG(L_ERROR,("fopen('%s',r) call failed (%s)\n",
			filename, strerror(errno)));
		info("%s missing ", MIMETYPES);
		rc = -1;
		goto bailout;
	}

	while (!feof(fp)) {
		char *type, *ext;

		if (NULL == fgets(line, MAXLINESIZE, fp))
			break;
		if (line[0] == '#')
			continue;
		if (line[0] == '\r' || line[0] == '\n')
			continue;

		type = strtok(line, "\t\r\n ");
		if (type) {
			mime_t *m;

			m = (mime_t *)xcalloc(sizeof(mime_t), 1);
			m->type = xstrdup(type);
			if (NULL == m->type) {
				LOG(L_ERROR,("xstrdup('%s') call failed (%s)\n",
					type, strerror(errno)));
				xfree(m);
				rc = -1;
				goto bailout;
			}

			ext = strtok(NULL, "\t\r\n ");
			if (ext) {
				m->numext = 0;
				m->ext = calloc(32, sizeof(char *));
				LOG(L_DEBUG,("MIME: type '%s'\n", type));
				do {
					while (*ext != '\0' && isspace(*ext))
						ext++;
					LOG(L_DEBUG,("MIME: extension #%d '%s'\n",
						m->numext, ext));
					m->ext[m->numext] = xstrdup(ext);
					m->numext += 1;
					ext = strtok(NULL, "\t\r\n ");
				} while (NULL != ext);
			}
			/* insert type into the linked list */
			m->next = mime;
			mime = m;
		}
	}
	info("%s ", MIMETYPES);

bailout:
	e = errno;
	if (NULL != fp) {
		fclose(fp);
		fp = NULL;
	}
	xfree(line);
	xfree(filename);
	errno = e;
	return rc;
}
